
// 自定义Promise构造函数, 并指定一个参数：excutor 执行器
function Promise(excutor){
    // 初始化状态属性值为pending
    this.PromiseState = "pending";
    // 初始化结果属性值为undefined
    this.PromiseResult = undefined;
    // 声明一个属性用于存放then没有执行的回调函数
    this.callbacks = [];
    
    // 声明内部成功函数
    const success = (v) => {
        // 若当前状态不是等待pending，则退出
        if(this.PromiseState != "pending"){
            return;
        }
        this.PromiseState = "fulfilled";
        this.PromiseResult = v;
        // 询问callbacks属性中是否存在需要执行回调（因为延迟导致没有执行的）
        if(this.callbacks.length > 0){
            this.callbacks.forEach(item =>{
                item.ok(this.PromiseResult);
            });
        }
        
    }

    // 声明内部失败函数
    const error = (r) => {
        // 若当前状态不是等待pending，则退出
        if(this.PromiseState != "pending"){
            return;
        }
        this.PromiseState = "rejected";
        this.PromiseResult = r;
        // 询问callbacks属性中是否存在需要执行回调（因为延迟导致没有执行的）
        if(this.callbacks.length > 0){
            this.callbacks.forEach(item =>{
                item.ng(this.PromiseResult);
            });
        }
    }
    try {
        // 调用执行器
        excutor(success,error);
    } catch (err) {
        error(err.message);
    }
    
}

// 为当前自定义Promise构造函数的原型上添加then方法
Promise.prototype.then = function(onFulfilled, onRejected){
    return new Promise((resolve, reject) => {
        //声明一个函数 『handle 处理的意思』
        const handle = (type) => {
            try {
                if(type === undefined){
                    reject(this.PromiseResult);
                    return;
                }
                // 获取成功回调的返回值
                let res = type(this.PromiseResult);
                // 判断返回结果是否是一个promise对象
                if(res instanceof Promise){
                    //若res是promise对象,那么通过then()来获取状态信息以及值
                    res.then(v => {
                        resolve(v);
                    },r => {
                        reject(r);
                    });
                } else {
                    // 若res是非promise的任意值,那么调用resolve()设置fulfilled, 
                    // 并将当前res作为value为返回的值
                    resolve(res);
                }
            } catch (err) {
                reject(err.message);
            }
        }
        // 根据当前promise对象的状态属性值来执行对应的回调函数
        if(this.PromiseState == "fulfilled"){
            // 调用上面的内部函数，实现成功状态的回调调用
            setTimeout(()=>{ // 异步操作
                handle(onFulfilled);
            });
        }
        if(this.PromiseState == "rejected"){
            setTimeout(()=>{ // 异步操作
                handle(onRejected);
            });
        }
        // 判断当前promise对象的状态是否是等待pending
        if(this.PromiseState == "pending"){
            // 将当前的回调函数保留下来，存到callbacks属性中
            this.callbacks.push({
                ok:()=>{handle(onFulfilled);},
                ng:()=>{handle(onRejected);} 
            });
        }
    });
}

// 为当前Promise构造函数的原型添加catch方法，实现promise的错误状态处理
Promise.prototype.catch = function(onRejected){
    // 此方法的功能是then的一半，所以我们可以执行调用then的一半就可以了
    return this.then(undefined, onRejected);
}

// 将Promise构造函数直接当成对象来添加 resolve 方法
Promise.resolve = function(value){
    return new Promise((resolve, reject)=>{
        //判断
        if(value instanceof Promise){
            //value 是 promise 对象
            value.then(resolve, reject);
        }else{
            //value 不是 promise 对象
            resolve(value);
        }
    });
}
// 将Promise构造函数直接当成对象来添加 reject 方法
Promise.reject = function(value){
    return new Promise((resolve, reject)=>{
        //判断
        reject(value);
    });
}

// 为Promise直接添加all方法，完成all()的功能
Promise.all = function(promises){
    // 返回一个Promise对象
    return new Promise((resolve, reject) => {
        const data = []; // 声明数组变量,用于存放每次promise成功的结果.  
        // 遍历所有的Promise参数对象
        promises.forEach(item => {
            // 调用每个promise对象的then方法
            item.then(v =>{
                console.log("成功", v);
                // 将成功的结果添加到数组data
                data.push(v);
                // 判断所有的promise都是成功， 且结果都放到了data中
                if( data.length === promises.length){
                    resolve(data);
                }
            }, r => {
                console.log("失败", r);
                reject(r);
            });
        });
    });
    
}

// 为Promise直接添加race方法，完成race()的功能
Promise.race = function(promises){
    // 返回一个Promise对象
    return new Promise((resolve, reject) => {
        // 遍历所有的Promise参数对象
        promises.forEach(item => {
            // 调用每个promise对象的then方法
            item.then(v =>{
                resolve(v);
            }, r => {
                reject(r);
            });
        });
    });
    
}



